﻿#pragma once
namespace LK
{
		template<>struct ptr<Reflection::LibraryNode >:ptr<Object>
		{
			PMETHODS(ptr,Reflection::LibraryNode);
			//构造函数
			ptr(weakptr<Reflection::TypeLibrary> const& library, Reflection::PDomainNode const&baseNode = ptr<Reflection::LibraryNode >::EmptyNode, ptr<String> const& name = ptr<String>::GetEmpty());
			//获取名称
			ptr<String> GetName()const;
			//获取全路径名称
			ptr<String> GetFullName()const;
			//获取基节点
			Reflection::PDomainNode GetBaseNode()const;
			//设置名称
			void SetName(ptr<String> const&)const;
			//设置基节点
			void SetBaseNode(Reflection::PDomainNode const&)const;
			//获取基库
			weakptr<Reflection::TypeLibrary> GetLibrary()const;
			//设置基库
			void SetLibrary(weakptr<Reflection::TypeLibrary> const&)const;
			//清理
			void Clear()const;
			/**
			@brief 比较两个节点的大小*/
			static index_t Compare(ptr<Reflection::LibraryNode > const&, ptr<Reflection::LibraryNode > const&);
			/**
			@brief 比较节点与字符串的大小*/
			static index_t StringCompare(ptr<Reflection::LibraryNode > const&, ptr<String> const&);
			//空节点
			static const Reflection::PDomainNode EmptyNode;
		};
	namespace Reflection
	{
		struct LibraryNode:Object
		{
			BMETHODS(ptr<Reflection::LibraryNode >, LibraryNode)
			//重写Object::ToString方法
			ptr<String> ToString()const;
			//构造函数，构造时必须传入基库弱引用
			LibraryNode(weakptr<TypeLibrary> const& library, PDomainNode const&baseNode= ptr<Reflection::LibraryNode >::EmptyNode,ptr<String> const& name=ptr<String>::GetEmpty());
			//获取基库
			weakptr<TypeLibrary> GetLibrary()const;
			//获取名称
			ptr<String> GetName()const;
			//获取基节点
			PDomainNode GetBaseNode()const;
			//设置基库
			virtual void SetLibrary(ptr<TypeLibrary> const&);
			//清理，清除所有引用和下属所有信息
			virtual void Clear();
			//设置名称
			void SetName(ptr<String> const&);
			//设置基节点
			void SetBaseNode(PDomainNode const&);
		private:
			//名称
			ptr<String> Name;
			//基节点
			ptr<LibraryNode > BaseNode;
			//基库
			weakptr<Object> Library;
		};

		struct PDomainNode :ptr<Reflection::LibraryNode >
		{
			PMETHODS(PDomainNode, DomainNode);
			/**
			@brief 获取内部节点数组的引用*/
			ptr<Collection::IArray<ptr<Reflection::LibraryNode >>>& GetInnerNodesRef()const;
			/**
			@brief 添加一个内部节点，并返回该节点，按节点名称进行排序。
			@note 如果已存在该名称节点，则直接返回内部保存的同名节点*/
			ptr<Reflection::LibraryNode > AddInnerNode(ptr<Reflection::LibraryNode > node)const;
			/**
			@brief 获取当前节点下一个名为str的子节点，如果没有指定名称的子节点，则返回NULL*/
			ptr<Reflection::LibraryNode > GetInnerNodeByName(ptr<String> const & str)const;
			/**
			@brief 移除指定的内部节点*/
			void RemoveInnerNode(ptr<Reflection::LibraryNode > const&node)const;
			/**
			@brief 构造一个域节点*/
			PDomainNode(weakptr<TypeLibrary> const& library, PDomainNode const&baseNode = ptr<Reflection::LibraryNode >::EmptyNode, ptr<String> const& name = ptr<String>::GetEmpty());
		};
		struct DomainNode :LibraryNode
		{
			BMETHODS(PDomainNode, DomainNode)
			/**
			@brief 内部节点数组*/
			ptr<Collection::IArray<ptr<Reflection::LibraryNode > >> InnerNodes;
			/**
			@brief 构造一个域节点*/
			DomainNode(weakptr<TypeLibrary> const& library, PDomainNode const&baseNode = ptr<LibraryNode >::EmptyNode, ptr<String> const& name = ptr<String>::GetEmpty());
			/**
			@brief 清理内部数据*/
			void Clear();
			/**
			@brief 添加一个内部节点，并返回该节点，按节点名称进行排序。
			@note 如果已存在该名称节点，则直接返回内部保存的同名节点*/
			ptr<Reflection::LibraryNode > AddInnerNode(ptr<Reflection::LibraryNode > node);
			/**
			@brief 获取当前节点下一个名为str的子节点，如果没有指定名称的子节点，则返回NULL*/
			ptr<Reflection::LibraryNode > GetInnerNodeByName(ptr<String> const & str)const;
		};
	}
}
